package com.tyut.musicdreamer.service.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tyut.musicdreamer.framework.starter.convention.exception.ClientException;
import com.tyut.musicdreamer.service.user.mapper.UserMapper;
import com.tyut.musicdreamer.service.user.model.dto.LoginRequest;
import com.tyut.musicdreamer.service.user.model.dto.RegisterRequest;
import com.tyut.musicdreamer.service.user.model.entity.User;
import com.tyut.musicdreamer.service.user.model.vo.TokenVO;
import com.tyut.musicdreamer.service.user.model.vo.UserVO;
import com.tyut.musicdreamer.service.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * 用户服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final BCryptPasswordEncoder passwordEncoder;
    
    @Value("${upload.avatar.base-path:/data/musicdreamer/avatar/}")
    private String avatarBasePath;
    
    @Value("${upload.avatar.allowed-extensions:jpg,jpeg,png,gif}")
    private String[] allowedExtensions;

    @Override
    @Transactional
    public UserVO register(RegisterRequest request) {
        // 检查用户名是否已存在
        if (checkUsernameExists(request.getUsername())) {
            throw new ClientException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (checkEmailExists(request.getEmail())) {
            throw new ClientException("邮箱已存在");
        }
        
        // 创建用户实体
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setRole("USER");
        user.setStatus(0);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setDeleted(0);
        
        // 保存用户
        save(user);
        
        // 转换为VO并返回
        return convertToUserVO(user);
    }

    @Override
    public TokenVO login(LoginRequest request) {
        // 根据用户名查询用户
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, request.getUsername())
                .eq(User::getDeleted, 0));
        
        // 验证用户存在性和密码正确性
        if (user == null || !passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new ClientException("用户名或密码错误");
        }
        
        // 检查账号状态
        if (user.getStatus() != 0) {
            throw new ClientException("账号已被禁用");
        }
        
        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        updateById(user);
        
        // 创建Token信息 - 不使用SaToken，仅返回用户信息和用户ID作为标识符
        // 实际的token将由网关层生成
        TokenVO tokenVO = new TokenVO();
        tokenVO.setUserId(user.getId()); // 添加用户ID作为标识符
        tokenVO.setUser(convertToUserVO(user));
        
        return tokenVO;
    }

    @Override
    public UserVO getUserInfo(Long userId) {
        User user = getById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new ClientException("用户不存在");
        }
        return convertToUserVO(user);
    }

    @Override
    public boolean checkUsernameExists(String username) {
        return count(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, username)
                .eq(User::getDeleted, 0)) > 0;
    }

    @Override
    public boolean checkEmailExists(String email) {
        return count(new LambdaQueryWrapper<User>()
                .eq(User::getEmail, email)
                .eq(User::getDeleted, 0)) > 0;
    }
    
    @Override
    @Transactional
    public UserVO updateUserInfo(Long userId, String username, String email) {
        User user = getById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new ClientException("用户不存在");
        }

        // 如果要修改用户名，检查是否已存在
        if (!user.getUsername().equals(username) && checkUsernameExists(username)) {
            throw new ClientException("用户名已存在");
        }

        // 如果要修改邮箱，检查是否已存在
        if (!user.getEmail().equals(email) && checkEmailExists(email)) {
            throw new ClientException("邮箱已存在");
        }

        user.setUsername(username);
        user.setEmail(email);
        user.setUpdateTime(LocalDateTime.now());

        updateById(user);

        return convertToUserVO(user);
    }

    @Override
    @Transactional
    public String updateAvatar(Long userId, MultipartFile file) {
        User user = getById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new ClientException("用户不存在");
        }
        
        try {
            // 确保目录存在
            Path uploadDir = Paths.get(avatarBasePath);
            if (!Files.exists(uploadDir)) {
                Files.createDirectories(uploadDir);
            }
            
            // 获取文件扩展名
            String originalFilename = file.getOriginalFilename();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            }
            
            // 检查文件类型
            boolean isAllowed = false;
            for (String allowedExt : allowedExtensions) {
                if (allowedExt.equalsIgnoreCase(extension)) {
                    isAllowed = true;
                    break;
                }
            }
            
            if (!isAllowed) {
                throw new ClientException("不支持的文件类型");
            }
            
            // 生成唯一文件名
            String fileName = UUID.randomUUID() + "." + extension;
            Path filePath = uploadDir.resolve(fileName);
            
            // 保存文件
            Files.copy(file.getInputStream(), filePath);
            
            // 更新用户头像
            String avatarUrl = "/api/avatars/" + fileName;
            user.setAvatar(avatarUrl);
            user.setUpdateTime(LocalDateTime.now());
            updateById(user);
            
            return avatarUrl;
        } catch (IOException e) {
            log.error("上传头像失败", e);
            throw new ClientException("文件上传失败");
        }
    }

    @Override
    @Transactional
    public boolean updatePassword(Long userId, String oldPassword, String newPassword) {
        User user = getById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new ClientException("用户不存在");
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new ClientException("原密码错误");
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        return updateById(user);
    }
    
    /**
     * 将用户实体转换为VO
     */
    private UserVO convertToUserVO(User user) {
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        // 不需要设置password，因为UserVO中没有这个字段
        return userVO;
    }
} 